home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
misc
/
emu
/
msh-156.lha
/
han
/
hancrtso.a
< prev
next >
Wrap
Text File
|
1996-12-22
|
9KB
|
382 lines
; $Id: hancrtso.a,v 1.56 1996/12/22 00:22:33 Rhialto Rel $
; $Log: hancrtso.a,v $
; Revision 1.56 1996/12/22 00:22:33 Rhialto
; Add private BeginIO().
;
; Revision 1.55 1993/12/30 23:02:45 Rhialto
; *** empty log message ***
;
; Revision 1.54 1993/06/24 05:12:49 Rhialto
; DICE 2.07.54R.
;
; Revision 1.53 92/10/25 02:21:25 Rhialto
; No change.
;
; Revision 1.51 92/04/17 15:34:37 Rhialto
; Freeze for MAXON.
;
; Revision 1.46 91/10/06 18:25:52 Rhialto
;
; Freeze for MAXON
;
; Revision 1.43 91/09/28 01:46:54 Rhialto
; Create regargs entrypoints for byte swap routines.
;
; Revision 1.42 91/06/14 00:07:56 Rhialto
; DICE conversion
;
resident equ 1 ; Do we handle RESIDENT (== pure) code?
; near a4 ; for A68k 2.7.1: also needs -m32766 for offset
; C.A
;
; (c)Copyright 1990, Matthew Dillon, All Rights Reserved
;
; Amiga startup code for non-resident and resident DCC
; programs.
;
; Modified for use with a DOS handler.
;
; DLINK:
;
; * __BSS_LEN : # long wrds of bss (occurs after DATA)
; * __DATA_LEN : # long wrds of initialized data to copy (if resident)
; * __DATA_BAS : base of data (read only if resident)
; * __RESIDENT : is this code residentable? If this variable
; is set then there are no absolute data/bss
; references except __DATA_BAS and there is
; NO BSS MEMORY ALLOCATED AFTER THE DATA
; SECTION.
;
; If this variable is not set then absolute
; references refer to the same storage as
; A4 relative accesses and uninitialized
; BSS space exists just after the data section.
;
; Note that in the large-data model + fragmented
; sections, there are usually real BSS hunks
; floating about that have been zerod by
; LoadSeg() (in this case __BSS_LEN could be 0)
;
; COMPILER:
;
; * If -r option specified when compiling then the compiler
; will generate autoinit code to handle data initialization
; that would otherwise require a reloc32 hunk.
;
; * If -r or -md specified compiler references all data items
; using A4-Relative addressing.
;
; C LIB CODE:
;
; * Resident: Allocate (__DATA_LEN+__BSS_LEN)*4
; Not Res : zero out preallocated BSS.
;
; * Generate A4 ref ptr to bss base + 32766 (uses Aztec's
; conventions).
;
; * All library code uses the SMALL-DATA with alternate
; BSS and DATA section names (based in this source
; file) so the linker puts library related data/bss
; first. BUT, BSS always comes after DATA unless
; you -frag the link (can't resident a frag'd link),
; so if there is more than 64KBytes of *initialized*
; data you must -frag the link.
section text,code
xref __RESIDENT ; (dlink), executable is residentable
xref __BSS_LEN ; (dlink), length of BSS
xref __DATA_BAS ; (dlink), base of initialized data
xref __DATA_LEN ; (dlink), length of data
xref _messydoshandler ; we call messydoshandler()
xref _LVOSetSignal
xref _LVOAllocMem
xref _LVOFreeMem
xref _LVOForbid
xref _LVOReplyMsg
xdef _exit ; we are exit()
xdef start
xdef _SysBase ; we export _SysBase
; xdef __WBMsg
MEMF_CLEAR equ $00000001
MEMF_PUBLIC equ $00010000
start:
; movem.l D2-D7/A2-A6,-(sp)
move.l 4,A6 ; EXEC base
move.l sp,A2
; move.l A0,-(sp) ; save arg for _main() call
; move.l D0,-(sp) ; save arglen for _main() call
; If we are flagged resident then there is NO BSS ALLOCATED
; If we are not flagged resident then BSS IS ALLOCATED AFTER DATA,
; BUT NOT CLEARED.
;ifne resident
move.w #__RESIDENT,D0
beq snotres
; Allocate BSS+DATA space and then copy static data.
move.l #__BSS_LEN,D0
add.l #__DATA_LEN,D0
asl.l #2,D0 ; x4
addq.l #8,D0 ; MemList header extra
move.l D0,D5 ; D5 = #bytes
move.l #MEMF_PUBLIC,D1
jsr _LVOAllocMem(A6)
tst.l D0
bne alok
move.l A2,sp
moveq.l #-1,D0
bra exfail
alok move.l D0,A0
clr.l (A0)+ ; MemList entry next ptr
move.l D5,(A0)+ ; MemList entry #bytes
lea 32766(A0),A4 ; SET A4
lea -8(A0),A3 ; A3 = MemList entry base
; can't copy to MemList(A4) yet
; Copy data to allocated copy
; A0 = dst
lea __DATA_BAS,A1 ; A1 = src
move.l #__DATA_LEN,D0 ; D0 = long words
bra bssent
bsslop move.l (A1)+,(A0)+
bssent dbf D0,bsslop
sub.l #$10000,D0
bcc bsslop
bra clrbss
;endc
; Not resident, BSS space has been allocated for us
; beyond the specified data, just load the base ptr
snotres lea __DATA_BAS,A4
lea 32766(A4),A4
sub.l A3,A3
clrbss
; CLEAR BSS &-32766(A4) + __DATA_LEN*4
lea -32766(A4),A0
move.l #__DATA_LEN,D0
asl.l #2,D0
add.l D0,A0
move.l #__BSS_LEN,D0 ; longwords of bss
moveq.l #0,D1
bra clrent
clrlop move.l D1,(A0)+
clrent dbf D0,clrlop
sub.l #$10000,D0
bcc clrlop
;ifne resident
move.l A3,___MemList(A4) ; memlist entry (if resident)
;endc
move.l A2,__ExitSP(A4) ; sp to restore
; moveq.l #0,D0 ; new signals
; move.l #$1000,D1 ; signal mask
; jsr _LVOSetSignal(A6) ; clear ^C
move.l A6,_SysBase(A4) ; resident segment.
; Return value of 0 indicates succcess. Flags
; have been set.
;ifne resident
jsr __AutoInit0 ; A6 has SYSBase
bne xfail
; pea 1.W ; autoconfig loader
; jsr __AutoConfig ; note, rt pulls stack
; addq.l #4,sp
jsr __AutoInit1 ; A6 has SYSBase
bne xfail
;endc
jsr _messydoshandler(PC)
; fall through to low level exit... this avoids referencing
; exit() if the user overides messydoshandler().
xfail
clr.l -(sp)
clr.l -(sp)
; _EXIT()
;
; since entry uses malloc we must free any incidental memory
; at __exit instead of _exit.
;
; ReplyMsg(_WBMsg) just before returning
_exit:
; pea -1.W
; jsr __AutoConfig ; note, rt pulls stack
; addq.l #4,sp
move.l _SysBase(A4),A6
;ifne resident
jsr __AutoExit1 ; A6 has SysBase
jsr __AutoExit0 ; A6 has SysBase
;endc
move.l __ExitSP(A4),A5 ; get sp... because we might free
; the space taken by the variable!
; move.l __WBMsg(A4),D6 ; D6 = WBMsg if it exists
;ifne resident
move.l ___MemList(A4),D0 ; free memory
beq ex20
ex10 move.l D0,A2
move.l (A2),A3 ; next...
move.l 4(A2),D0 ; bytes
move.l A2,A1 ; ptr
jsr _LVOFreeMem(A6)
move.l A3,D0 ; next...
bne ex10
;endc
ex20
move.l 4(sp),D0 ; get exit code
move.l A5,sp ; restore sp
; tst.l D6 ; reply to workbench msg if it
; beq ex30 ; exists
; jsr _LVOForbid(A6) ; forbid through exit
; move.l D6,A1
; jsr _LVOReplyMsg(A6)
ex30
; FINIS, poof.
exfail
; movem.l (sp)+,D2-D7/A2-A6
rts
; Base of autoinit section
;ifne resident
section autoinit0,code
__AutoInit0:
section autoinit1,code
__AutoInit1:
section autoexit0,code
__AutoExit0:
section autoexit1,code
__AutoExit1:
;endc
; section autoconfig,code
;__AutoConfig:
; All library C code is compiled with the -S option
; which uses 'libdata' and 'libbss' section names,
; forcing library data to come before program data
; and library bss to come before program bss (because
; library data/bss sections are declared here first
; and sections of like name are coagulated).
section libdata,data
_Reserved dc.l 0 ; force section to exist (dummy)
section libbss,bss
_SysBase ds.l 1
__ExitSP ds.l 1
;__WBMsg ds.l 1
;ifne resident
xdef ___MemList ; used by malloc/free
___MemList ds.l 1
;endc
;;;;
;
; Some byte-swapping routines for extra bonus points.
;
; word Get8086Word(A0 byte *Word8086);
; word OtherEndianWord(D0 long oew); /* long should become word */
; ulong OtherEndianLong(D0 ulong oel);
;
section text,code
xdef _Get8086Word
xdef @Get8086Word
_Get8086Word:
move.l 4(sp),a0 ; get (unaligned) address
@Get8086Word:
move.b (a0)+,d1 ; get low order byte
move.b (a0),d0 ; get high order byte
asl.w #8,d0 ; shift it into position
move.b d1,d0 ; put in the low order byte
rts
xdef _OtherEndianWord
xdef @OtherEndianWord
_OtherEndianWord:
move.w 4+2(sp),d0 ; arg is passed as a long for now
@OtherEndianWord:
rol.w #8,d0
rts ; we leave junk in the high word of d0.
xdef _OtherEndianLong
xdef @OtherEndianLong
_OtherEndianLong:
move.l 4(sp),d0
@OtherEndianLong:
rol.w #8,d0
swap d0
rol.w #8,d0
rts
;;;;
;
; Glue for the disk change interrupt handler. A4 is now in A1 (is_Data).
; We only need this when we compile for PURE code, but it won't harm
; either.
xref _ChangeIntHand
xdef _ChangeIntHand0
_ChangeIntHand0:
move.l a4,-(sp)
movea.l a1,a4
jsr _ChangeIntHand ; C code
move.l (sp)+,a4
rts
; BeginIO(ior)
section text,code
xdef _hyper_BeginIO
xdef _BeginIO
xdef @BeginIO
_hyper_BeginIO:
_BeginIO:
move.l 4(sp),A0
@BeginIO:
move.l A6,-(sp)
move.l A0,A1
move.l $14(A0),A6 ; io_Device
jsr -30(A6)
move.l (sp)+,A6
rts
END